package dm.ast.model.gen.factory;

import test.utility.Randomly;

import java.util.ArrayList;
import java.util.List;

public class WheModelFactory extends BaseModelFactory{
    //根据宽度、深度，返回查询列模型
    public static ComplexityModel whereModels(int wid_t , int dep_t){
        List<ComplexityModel> models = new ArrayList<ComplexityModel>();

        //1、极值分配
        models.addAll((modelExtreme(wid_t , dep_t)));

        //2、深度平均分配
        if(wid_t > estimateMinWidt(dep_t)){
            models.addAll(modelAverage(wid_t , dep_t));
        }

        return Randomly.fromList(models);
    }

    //极值分配
    public static List<ComplexityModel> modelExtreme(int wid_t , int dep_t){
        List<ComplexityModel> extreme = new ArrayList<ComplexityModel>();
        ComplexityModel model;

        //仅一个bool表达式
        model = new ComplexityModel(1);
        model.comps[0].wid_t = wid_t;
        model.comps[0].dep_t = dep_t;
        extreme.add(model);

        //尽可能多的bool表达式，随便选择一个bool表达式深度设为dep_t
        //避免出现/*w:3,d:4*/这样的复杂度需求
        if(wid_t > estimateMinWidt(dep_t)){
            int cnt = (wid_t - estimateMinWidt(dep_t))/FactoryConstant.MIN_EXP_WIDT + 1;
            model = new ComplexityModel(cnt);
            for (int i = 0; i < model.count; i++) {
                model.comps[i].wid_t = FactoryConstant.MIN_EXP_WIDT;
                model.comps[i].dep_t = 1;
            }
            int j = r.getInteger(0 , model.count);
            model.comps[j].dep_t = dep_t;
            model.comps[j].wid_t = wid_t - (cnt - 1)*FactoryConstant.MIN_EXP_WIDT;
            extreme.add(model);
        }
        return extreme;
    }


    //深度平均分配
    public static List<ComplexityModel> modelAverage(int wid_t , int dep_t){
        List<ComplexityModel> average = new ArrayList<ComplexityModel>();
        //避免出现/*w:3,d:4*/这样的复杂度需求
        if(wid_t > estimateMinWidt(dep_t)){
            int tmp_widt_used = 0;
            int i;
            int tmp_dept = 0;
            boolean maxDeptFlag = false;
            ComplexityModel model = new ComplexityModel(wid_t/FactoryConstant.MIN_EXP_WIDT + 1);
            for (i = 0; i < model.count; i++) {
                tmp_dept = r.getInteger(1 , dep_t + 1);
                model.comps[i].dep_t = tmp_dept;
                if(tmp_dept == dep_t){
                    maxDeptFlag = true;
                }
                //todo
                //此处仅考虑了表达式最小宽度
                //需要实现根据剩余宽度随机分配
                if(tmp_dept == 1){
                    model.comps[i].wid_t = FactoryConstant.MIN_EXP_WIDT;

                }else {
                    model.comps[i].wid_t = setWidtByDept(model.comps[i].dep_t);
                }
                tmp_widt_used += model.comps[i].wid_t;
                if(tmp_widt_used >= wid_t){  //宽度已满足
                    model.count = i;//提前结束，原定的count数目需要根据实际情况修改
                    break;
                }

            }
            if(maxDeptFlag){  //如果没有使用到对大宽度，那么在已经生成的模型中随机选择一个设置为最大宽度
                int j = r.getInteger(0 , i);
                model.comps[j].dep_t = dep_t;
                model.comps[j].wid_t = setWidtByDept(dep_t);
            }
            average.add(model);

        }
        return average;
    }
}
